home *** CD-ROM | disk | FTP | other *** search
- /*
- * junkf.c - routines for manipulating the "junk" folder
- */
- #include "RevRdist.h"
- #include "dispatch.h"
- #include <TransSkelProto.h>
- #include <TransDisplayProto.h>
-
- /*
- * prototype for local function
- */
- static Integer testJunk(cnode_t *);
-
- /*
- *=========================================================================
- * cleanJunk () - get rid of old files in "junk" folder
- *=========================================================================
- */
-
- DISPATCHED (cleanJunk)
- {
- struct lm /* local memory */
- {
- frame_t f;
- };
- typedef struct lm lm_t;
- register lm_t * m; /* pointer to local memory */
- OSErr error;
- file_info_t * fi; /* ptr to junk entry in File_list[] */
- StringPtr p; /* temp */
- Ptr paramv[2];
- short result; /* our result */
- StringHandle sh; /* temp */
-
- m = *(lm_t **)fh;
- result = request;
- error = 0;
- switch (request)
- {
- case R_INIT:
- if (ClueID = resizeFrame (fh, sizeof (lm_t)))
- return R_ERROR;
- m = *(lm_t **)fh;
- m->f.state = 1;
- return R_CONT;
-
- case R_CONT:
- /*
- * The bulk of the work is just setting up for emptyFolder.
- * Everything is done in state 1.
- */
- fi = &File_list[FL_JUNK];
- if (m->f.state == 1)
- {
- if (fi->f_vol == 0 || fi->f_set == 0)
- {
- /*
- * Mention it if there is no junk folder
- */
- if (sh = Prefs[P_WORK].p[PS_JUNKF])
- {
- HLock ((Handle)sh);
- p = *sh;
- }
- else
- p = (SP) "\p<unknown>";
- dispIndStr (ActivityWind, L_SKIP, LST_STR, p, nil);
- result = R_CONT;
- if (sh)
- HUnlock ((Handle)sh);
- result = popCall (R_CONT, nil);
- break;
- }
- /*
- * Tell 'em what we're doing
- */
- if (Flags & DB_VERBOSE)
- {
- sh = fi->f_path;
- HLock ((Handle)sh);
- dispIndStr (ActivityWind, L_DOJUNK, LST_STR, *sh, nil);
- HUnlock ((Handle)sh);
- }
- /*
- * Use the File_list catalog entry for junk folder for emptyFolder()
- */
- m->f.state = 2;
- paramv[0] = (Ptr)&fi->f_info;
- paramv[1] = (Ptr)testJunk;
- return (pushCall (emptyFolder, paramv));
- }
- else if (m->f.state == 2)
- {
- m->f.state = 3;
- return result; /* just allow emptyFolder to exit */
- }
- /*
- * Else, fall into
- */
- default:
- result = popCall (result, nil);
- break;
- }
- return result;
- }
-
-
-
- /*
- *=========================================================================
- * makeJunk () - create junk folder
- * entry: junk folder name given by preferences string
- * returns: OSErr
- *=========================================================================
- */
-
-
- OSErr
- makeJunk ()
- {
- OSErr error;
- file_info_t * fi; /* ptr into File_list for junk folder */
- StringHandle sh; /* name of junk folder */
- HParamBlockRec hpb; /* for PBDirCreate, etc */
- Str255 s; /* string temp */
-
- error = fnfErr;
- s[0] = 0;
- sh = Prefs[P_WORK].p[PS_JUNKF];
- while (sh && **sh) /* "while" is so can use "break" */
- {
- /*
- * We always try to create the junk folder, even though that will
- * often fail. But it's just as fast as checking to see if the
- * folder exists.
- */
- COPYPS (*sh, s);
- ZERO (hpb);
- hpb.fileParam.ioNamePtr = s;
- hpb.fileParam.ioVRefNum = ClientVol;
- hpb.fileParam.ioDirID = ClientRoot;
- error = PBDirCreate (&hpb, false);
- switch (error)
- {
- case noErr: /* folder created */
- break;
- case vLckdErr: /* if volume locked, switch to LISTONLY */
- case wPrErr:
- Flags |= DB_LISTONLY;
- /* fall into ... */
- case dupFNErr: /* if already exists, not an error */
- error = 0;
- break;
- }
- if (error) /* if trouble already */
- break;
- fi = &File_list[FL_JUNK];
- fi->f_ref = 0;
- fi->f_vol = ClientVol;
- error = getInfoByPath (s, fi);
- break;
- }
- if (error)
- {
- warning (E_NOJUNK, s, nil);
- error = 0;
- }
- return error;
- }
-
-
-
- /*
- *=========================================================================
- * moveToJunk (cp) - move file/folder to junk folder
- * entry: cp = pointer to client catalog list node
- * returns: 0 on success, else OSErr
- *=========================================================================
- */
- OSErr
- moveToJunk (cp)
- register cnode_t * cp;
- {
- OSErr error;
- file_info_t * fi; /* ptr to File_list for junk */
- int i,j; /* temps */
- char * s;
- CMovePBRec cpb; /* PBCatMove param block */
- HParamBlockRec pb; /* PBHRename param block */
- Byte junkname[32]; /* new name for existing junk file */
-
- fi = &File_list[FL_JUNK];
- if (fi->f_set == 0)
- {
- /* if no junk directory, skip it */
- notice (L_SKPJUNK, cp->name, nil);
- return 0;
- }
- if (cp->dirID == fi->f_info.dirID)
- return 0; /* cannot move junk into itself */
- notice (L_JUNKING, cp->name, nil);
- if (Flags & DB_LISTONLY)
- return 0;
- retry:
- ZERO (cpb);
- cpb.ioNamePtr = cp->name;
- cpb.ioVRefNum = ClientVol;
- cpb.ioDirID = cp->parID;
- cpb.ioNewName = fi->f_info.name;
- cpb.ioNewDirID = fi->f_info.parID;
- error = PBCatMove (&cpb, false);
- s = "\pPBCatMove";
- /*
- * If the move fails, it might be because there is already something
- * there by the same name. If so, rename the existing file/folder
- * and try moving again.
- */
- if (error == dupFNErr)
- {
- COPYPS (cp->name, junkname);
- do
- {
- /*
- * We try several possible names to rename the conflicting
- * file/folder out of the way.
- * The first is just to append the Junksuf string to the name.
- * If that won't fit, we replace the end of the name with
- * Junksuf.
- * If the result still conflicts, we increment the last character
- * of the name until we get no conflict or we run out of
- * "nice" characters, where "nice" is defined as "differing
- * from the last char of Junksuf only in the low 5 bits".
- */
- j = Junksuf[0];
- i = junkname[0];
- if (i < 31)
- {
- if (i + j > 31)
- i = 31 - j;
- junkname[0] = i + j;
- for (;j;j--)
- junkname[i+j] = Junksuf[j];
- }
- else
- {
- j = junkname[i];
- if ((j & 0x1f) != 0x1f)
- junkname[i] = j+1;
- else
- return error;
- }
- ZERO (pb);
- pb.ioParam.ioNamePtr = cp->name;
- pb.ioParam.ioVRefNum = ClientVol;
- pb.ioParam.ioMisc = (Ptr) junkname;
- pb.fileParam.ioDirID = fi->f_info.dirID;
- error = PBHRename (&pb, false);
- s = "\pPBHRename";
- } while (error == dupFNErr);
- if (error == 0)
- goto retry;
- }
- if (error)
- {
- ClueID = error;
- notice (L_SYS, (SP)"\pmoveToJunk", (SP) s, nil);
- }
- else
- statMsgClr ();
- return error;
- }
-
-
-
- /*
- *=========================================================================
- * testJunk (cp) - decide if file/folder should be discarded from junk
- * entry: cp = pointer to catalog list entry for file/folder
- * Junkp, ClientSp set
- * returns: 0 if file/folder should not be discarded
- * <> 0 if it should
- *=========================================================================
- */
- static
- Integer
- testJunk (cp)
- register cnode_t * cp;
- {
- register Integer result;
- static unsigned long now = 0;
-
- if (now == 0)
- GetDateTime ((long *)&now);
- if (cp->ctype == C_FOLDER)
- result = true; /* always junk (contents of) folders */
- else if (cp->mdDate + Prefs[P_WORK].p_jparam.max < now)
- result = true; /* if modified long ago */
- else if (cp->mdDate + Prefs[P_WORK].p_jparam.min > now)
- result = false; /* if changed recently */
- else if (ClientSp < Prefs[P_WORK].p_jparam.space)
- result = true; /* if short on space */
- else
- result = false;
- if (result && cp->ctype == C_FILE)
- ClientSp += (cp->in.f.fileLen + cp->in.f.rsrcLen);
- return result;
- }